package org.mycub.server.requester;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mycub.server.JettyServer;
import org.mycub.server.parser.CollectItem;
import org.opengis.feature.simple.SimpleFeature;


public class UpdaterAgent extends Thread{

	CollecterAgent callAgent;
	long timeToSleep;
	
	public UpdaterAgent(){
		callAgent = new CollecterAgent();
		setTimeToSleep(callAgent.getMinTimeToRefresh());
	}

	public CollecterAgent getCallAgent() {
		return callAgent;
	}

	public void setCallAgent(CollecterAgent callAgent) {
		this.callAgent = callAgent;
	}

	public long getTimeToSleep() {
		return timeToSleep;
	}

	public void setTimeToSleep(long timeToSleep) {
		this.timeToSleep = timeToSleep;
	}

	public void run(){
		try {
			while(true){
				long start = JettyServer.getTime();
				
				updateCUBData();
				updateODATABordeaux();
				
				long stop = JettyServer.getTime();
				
				System.out.println("\nMongo Database refreshed in : " + TimeUnit.MILLISECONDS.toSeconds(stop - start) + " secs");
				System.out.println("\n\nNext Surveillance in : " + TimeUnit.MILLISECONDS.toSeconds(getTimeToSleep()) + " secs\n\n");
				
				Thread.sleep(getTimeToSleep());
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}


	public void updateCUBData(){
		try {

			// Création d'une map de collections de features
			List<DataFile> featureCollections = this.getCallAgent().getFeaturesCollections();
			System.out.println("\n\nData found from the CUB : " + featureCollections.size());

			// Pour chaque collection de features correspondant à un objet recherché
			for(DataFile aFile : featureCollections){

				SimpleFeatureCollection featureCol = (SimpleFeatureCollection) aFile.getResultat();
				System.out.println("\nType of data : " + aFile.getSource().getSimpleName() +" number = " + featureCol.size());

				try (FeatureIterator<SimpleFeature> iterator = featureCol.features()){
					// On parcourt tous les objets du type item souhaité
					while( iterator.hasNext() ){

						Class<?> collecterClass = aFile.getCollecter();
						CollectItem collecter = (CollectItem) collecterClass.newInstance();

						SimpleFeature feature = iterator.next();
						collecter.collect(feature);		

					}
				}
			}

		} 
		catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	public void updateODATABordeaux(){
		try {
			
			// Création d'une map de collections de JSON
			List<DataFile> jsonCollections = this.getCallAgent().getJSONCollections();

			System.out.println("\n\nData found from ODataBordeaux : " + jsonCollections.size());

			// Pour chaque collection de json correspondant à un objet recherché
			for(DataFile aFile : jsonCollections){

				String jsonCol = (String) aFile.getResultat();				

				JSONObject jo = new JSONObject(jsonCol);
				JSONArray ja = jo.getJSONArray("d");
				int size = ja.length();
				System.out.println("\nType of data : " + aFile.getSource().getSimpleName() +" number = " + size);

				for (int i = 0; i < size; i++) {

					JSONObject objectJSON = ja.getJSONObject(i);
					Class<?> collecterClass = aFile.getCollecter();
					CollectItem collecter = (CollectItem) collecterClass.newInstance();
					collecter.collect(objectJSON);
				}			
			}
		} catch (InstantiationException | IllegalAccessException | IOException | JSONException e) {
			e.printStackTrace();
		}
	}

}
